/* gpioblink - blinks gpio line with given frequency
 * args: frequency, in Hz, floating point
 *
 * author: maciek gajewski
 *  date: 14.02.2005
 * license: GPL
 */
 
 
#include <stdio.h>
#include "libgpio.h"
#include <sys/time.h>

void blink(int line, double freq);

/* ------------------------- main ------------------------ */
int main(int argc, char** argv){
	
	double freq;
	int line;
		/* arg test� */
	if(argc<3){
		fprintf(stderr, "Usage: gpioblink <line> <freq (Hz, float) >\n");
		return 1;
	}
		/* parsing line arg */
	if(sscanf(argv[1], "%d", &line) != 1){
		fprintf(stderr, "gpioblink: '%s' si not correct GPIO line number\n", argv[1]);
		return 2;
	}
		/* parsing freqw arg */
	if(sscanf(argv[2], "%lf", &freq) != 1){
		fprintf(stderr, "gpioblink: '%s' is not correct floating-point frequency\n", argv[2]);
		return 2;
	}
	
		/* blinky-blinky */
	blink(line, freq);
	
	return 0;
}
/* ---------------------- microsleep ------------------------ */
/** sleep in microseconds*/
void microsleep(int microseconds)
{
	struct timeval tv;
	struct timezone tz;
	unsigned int start, end;
			
		/* start time */
	if( gettimeofday(&tv, &tz) != 0 ){
		return;
	}
	start = tv.tv_sec*1000 + tv.tv_usec/1000;
	
	while(1){
		if( gettimeofday(&tv, &tz) != 0 ){
			return;
		}
			/* enough? */
		end = tv.tv_sec*1000 + tv.tv_usec/1000;
		if(end-start > microseconds){
			return;
		}
	}
}

/* ------------------------- blink --------------------------- */
void blink(int line, double freq)
{
	unsigned int interval;
	gpio_state state;
		
		/* start, in milliseconds */
	interval = 500.0/freq;
		/* initialize line */
	state.direction = LG_GPIO_OUT;
	state.function = LG_FN_GPIO;
	
	gpio_init();
		/* blinking loop */
	while(1){
			/* set */
		state.state = 1;
		gpio_set(line, &state);
			/* wait */
		microsleep(interval);
			/* clear */
		state.state = 0;
		gpio_set(line, &state);
			/* wait */
		microsleep(interval);
	}
}
